window.maps = {};
maps.init = function() {
    let img = mapImage();
    $.get('/imgsize?img=' + img, function(e) {
        let w = e[0];
        let h = e[1];
        var extent = [0, 0, w, h];
        var projection = new ol.proj.Projection({
            code: 'xkcd-image',
            units: 'pixels',
            extent: extent
        });
        maps.editSource = new ol.source.Vector();
        let theStyle = maps.styles[window.mapStyle].defaultStyle();
        maps.mapVector = new ol.layer.Vector({
            source: maps.editSource,
            style: function(feature) {
                if (feature.getProperties() && feature.getProperties().icon != undefined) {
                    if (maps.styles[window.mapStyle].defaultIcon != undefined)
                        theStyle.setImage(maps.styles[window.mapStyle].defaultIcon(feature.getProperties().icon));
                }
                return theStyle;
            }
        });
        maps.map = new ol.Map({
            layers: [
                new ol.layer.Image({
                    source: new ol.source.ImageStatic({
                        url: '/mapimage/' + img, //这里添加静态图片的地址
                        projection: projection,
                        imageExtent: extent
                    })
                }), maps.mapVector
            ],
            target: 'map',
            view: new ol.View({
                projection: projection,
                center: ol.extent.getCenter(extent),
                zoom: 2,
                maxZoom: 8
            }),
            //controls: [],
            loadTilesWhileAnimating: true
        });
        if (maps.styles[window.mapStyle] && maps.styles[window.mapStyle].draw) {
            maps.styles[window.mapStyle].draw();
        }
        let selectClick = new ol.interaction.Select({  
            condition: ol.events.condition.singleClick,
              filter: (feature, layer) => {        
                return layer === maps.mapVector; // 需要添加事件的layer                            
            }
        });

        // 地图实例中加入事件
        selectClick.on('select', event => { 
            if (event.selected[0] == null)
                return;  
            let selectedFeat = event.selected[0];
            if (maps.styles[window.mapStyle] && maps.styles[window.mapStyle].info) {
                maps.styles[window.mapStyle].info(selectedFeat);
            }
            // 在使用ol.interaction.Select进行点击时，默认会把点击选中的要素显示在地图上
            // 可以用以下方法解决
            selectClick.getFeatures().clear();  

        });
        maps.map.addInteraction(selectClick);
    });
};

maps.clearAction = function() {
    let map = maps.map;
    if (maps.draw)
        map.removeInteraction(maps.draw);
    if (maps.snap)
        map.removeInteraction(maps.snap);
    if (maps.select)
        map.removeInteraction(maps.select);
    if (maps.modify)
        map.removeInteraction(maps.modify);
    if (maps.copy)
        map.removeInteraction(maps.copy);
    if (maps.transform)
        map.removeInteraction(maps.transform);
};
maps.regEdit = function(type) {
    let map = maps.map;
    maps.clearAction();
    if (type === 'Pan') {
        return;
    }
    if (type === 'Drag') {
        maps.select = new ol.interaction.Select({ wrapX: false });
        maps.map.addInteraction(maps.select);
        maps.translate = new ol.interaction.Translate({ source: maps.editSource });
        maps.map.addInteraction(maps.translate);
    } else if (type === 'Edit') {
        maps.select = new ol.interaction.Select({ wrapX: false });
        maps.modify = new ol.interaction.Modify({ source: maps.editSource });
        maps.map.addInteraction(maps.select);
        maps.map.addInteraction(maps.modify);
        maps.modify.on('modifyend', function(e) {
            let feat = e.features.getArray()[0];
            $.post('/savegeometry', {
                img: window.mapImage(),
                id: feat.getId(),
                geom: JSON.stringify(feat.getGeometry().getCoordinates())
            }, function(e) {
                if (e.status == 200) {
                    layui.layer.msg('修改成功');
                }
            });
        });


        let map = maps.map;
        maps.transform = new ol.interaction.Transform({
            addCondition: ol.events.condition.shiftKeyOnly
        });
        maps.transform.on(['translateend', 'rotateend', 'scaleend'], function(e) {
            let feat = e.feature;
            $.post('/savegeometry', {
                img: window.mapImage(),
                id: feat.getId(),
                geom: JSON.stringify(feat.getGeometry().getCoordinates())
            }, function(e) {
                if (e.status == 200) {
                    layui.layer.msg('修改成功');
                }
            });
        })
        map.addInteraction(maps.transform);

        maps.copy = new ol.interaction.CopyPaste({
            destination: maps.mapVector.getSource(),
            features: maps.transform.getFeatures()
        });
        map.addInteraction(maps.copy);
        // Remove selection if cut
        maps.copy.on('cut', function(e) {
            maps.transform.select();
        });
        maps.copy.on('paste', function(e) {
            maps.transform.select();
            e.features.forEach(function(f) {
                maps.transform.select(f, true);
            });
        });
        map.addControl(new ol.control.Bar({
            controls: [
                new ol.control.Button({
                    html: 'C',
                    handleClick: function() {
                        maps.copy.copy({ silent: false });
                    }
                }),
                new ol.control.Button({
                    html: 'X',
                    handleClick: function() {
                        maps.copy.copy({ cut: true, silent: false });
                    }
                }),
                new ol.control.Button({
                    html: 'V',
                    handleClick: function() {
                        maps.copy.paste({ silent: false });
                    }
                })
            ]
        }))
    } else if (type === 'Delete') {
        if (maps.select == undefined) return;
        let fs = maps.select.getFeatures();
        maps.editSource.removeFeature(fs.getArray()[0]);
    } else {
        let typeSelect = type;
        maps.draw = new ol.interaction.Draw({
            source: maps.editSource,
            type: typeSelect
        });
        map.addInteraction(maps.draw);
        maps.snap = new ol.interaction.Snap({ source: maps.editSource });
        map.addInteraction(maps.snap);
        maps.draw.on('drawend',
            function(event) {
                //event.feature.setStyle(curMap.defaultPolyStyle);
                let format = new ol.format.GeoJSON();
                let geometry = format.writeGeometryObject(event.feature.getGeometry());
                var id = geometry.type + "_" + window.guid();
                event.feature.setId(id);
                let img = mapImage();

                $.post('/savegeometry', {
                    img: img,
                    id: id,
                    geom: JSON.stringify(geometry.coordinates)
                }, function(e) {
                    if (e.status == 200) {
                        let theID = e.id;
                        $.get('/html/addproperties.html', function(html) {
                            layui.layer.open({
                                title: '编辑要素属性信息',
                                area: ['800px', '750px'],
                                type: 1,
                                shade: 0,
                                resize: false,
                                maxmin: false,
                                content: html
                            });
                            $('.layui-form input[name=featureid]').val(theID);
                            prop.loadIcons();
                            prop.addIcon();
                            prop.UploadImg();
                        });
                    }
                });
            });
    }
}

maps.drawFeatures = function(features) {
    maps.editSource.clear();
    for (let index = 0; index < features.length; index++) {
        const f = features[index];
        let feat = new ol.Feature();
        let geom;
        if (f.type == 'Point') {
            geom = new ol.geom.Point(f.geometry);
        } else if (f.type == 'LineString') {
            geom = new ol.geom.LineString(f.geometry);
        } else if (f.type == 'Polygon') {
            geom = new ol.geom.Polygon(f.geometry);
        }
        feat.setGeometry(geom);
        feat.setProperties(f.properties);
        feat.setId(f.featureid);
        maps.editSource.addFeature(feat);
        if (maps.styles[window.mapStyle] && maps.styles[window.mapStyle].featureAdded) {
            maps.styles[window.mapStyle].featureAdded(feat);
        }
    }
}
maps.styles = {
    'default': {
        featureAdded: function(feature) {
            let feat = new ol.Feature();
            let center = ol.extent.getCenter(feature.getGeometry().getExtent());
            let geom = new ol.geom.Point(center);
            feat.setGeometry(geom);
            let textStyle = new ol.style.Text({
                font: '14px Calibri,sans-serif',
                overflow: true,
                fill: new ol.style.Fill({
                    color: 'rgba(30, 30, 30, 1)'
                }),
                backgroundFill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0.6)'
                }),
                backgroundStroke: new ol.style.Stroke({
                    color: '#333',
                    width: 1,
                    lineCap: 'round',
                    lineJoin: 'round'
                }),
                padding: [4, 4, 4, 4],
                text: feature.getProperties().featurename
            });
            let style = new ol.style.Style({ text: textStyle });
            maps.editSource.addFeature(feat);
            feat.setStyle(style);
            feat.isLabel = true;
            feat.relatedFeatID = feature.getGeometry(feature.getId());
            feat.setProperties(feature.getProperties());
        },
        selectedIcon: function(path) {
            if (path == undefined || path.length == 0) path = '/images/icon.png';
            return new ol.style.Icon({
                anchor: [0.5, 1],
                src: path,
                scale: 1.1,
                rotation: 0.01
            });
        },
        selectedStyle: function() {
            return new ol.style.Style({
                fill: new ol.style.Fill({
                    color: 'rgba(160, 160, 160, 0.9)'
                }),
                stroke: new ol.style.Stroke({
                    color: 'rgba(160, 160, 160, 0.9)',
                    width: 4
                }),
                image: maps.styles['default'].selectedIcon()
            })
        },
        defaultIcon: function(path) {
            if (path == undefined || path.length == 0) path = '/images/icon.png';
            return new ol.style.Icon({
                anchor: [0.5, 1],
                src: path,
                scale: 1.0,
                rotation: 0.01
            });
        },
        defaultStyle: function() {
            return new ol.style.Style({
                fill: new ol.style.Fill({
                    color: 'rgba(222, 222, 222, 0.9)'
                }),
                stroke: new ol.style.Stroke({
                    color: 'rgba(222, 222, 222, 0.9)',
                    width: 4
                }),
                image: maps.styles['default'].defaultIcon()
            })
        },
        draw: function() {
            /*
            let r3D = new ol.render3D({
                style: new ol.style.Style({
                    stroke: new ol.style.Stroke({
                        color: 'rgba(255, 255, 255, 0.0)',
                        width: 0
                    }),
                    fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.9)' })
                }),
                //ghost: true,
                height: 5,
                maxResolution: 10,
                defaultHeight: 5
            });*/
            //maps.mapVector.setRender3D(r3D);
            // 监测鼠标放到屏幕上的事件
            maps.lastSelectedFeatureOnMove = null;
            maps.map.on('pointermove', function(e) {
                var pixel = maps.map.getEventPixel(e.originalEvent);
                var feature = maps.map.forEachFeatureAtPixel(pixel,
                    function(feature) {
                        return feature;
                    }, { hitTolerance: 10 }
                )
                if (maps.lastSelectedFeatureOnMove != null) {
                    if (maps.lastSelectedFeatureOnMove.isLabel === true) {
                        let selStyle = maps.lastSelectedFeatureOnMove.getStyle();
                        selStyle.getText().setPadding([4, 4, 4, 4]);
                        maps.lastSelectedFeatureOnMove.setStyle(selStyle);
                    } else {
                        maps.lastSelectedFeatureOnMove.setStyle(null);
                    }
                }
                if (feature === undefined) {
                    maps.map.getTargetElement().style.cursor = "auto"
                } else {
                    if (feature && feature.isLabel === true) {
                        let selStyle = feature.getStyle();
                        selStyle.getText().setPadding([6, 6, 6, 6]);
                        feature.setStyle(selStyle);
                    } else {
                        if (feature.getGeometry().getType() == 'Point') {
                            let theStyle = maps.styles[window.mapStyle].defaultStyle();
                            let theImg = maps.styles[window.mapStyle].defaultIcon(feature.getProperties().icon);
                            theImg.setScale(1.1);
                            theStyle.setImage(theImg);
                            feature.setStyle(theStyle);
                        } else {
                            let theStyle = maps.styles[window.mapStyle].selectedStyle();
                            feature.setStyle(theStyle);
                        }
                        maps.map.getTargetElement().style.cursor = "pointer";
                    }
                    maps.lastSelectedFeatureOnMove = feature;
                }
            });
        },
        info: function(selectedFeat) {
            let properties = selectedFeat.getProperties();
            let info = window.allProperties(properties, ['geometry']);
            alert(info);
        }
    },
    'admin': {
        draw: function() {},
        defaultStyle: function() {
            return new ol.style.Style({
                fill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0.2)'
                }),
                stroke: new ol.style.Stroke({
                    color: '#ffcc33',
                    width: 2
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    stroke: new ol.style.Stroke({
                        width: 0
                    }),
                    fill: new ol.style.Fill({
                        color: '#ffcc33'
                    })
                })
            })
        }
    }
};

maps.panByFeatureid = function(featureid) {
    let feat = maps.editSource.getFeatureById(featureid);
    feat.setStyle(new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(255, 30, 30, 0.2)'
        }),
        stroke: new ol.style.Stroke({
            color: '#ff3333',
            width: 4
        }),
        image: new ol.style.Circle({
            radius: 7,
            stroke: new ol.style.Stroke({
                width: 4
            }),
            fill: new ol.style.Fill({
                color: '#ff3333'
            })
        })
    }));
    //maps.map.getView().fit(feat.getGeometry());
    let center = ol.extent.getCenter(feat.getGeometry().getExtent());
    maps.map.getView().animate({ center: center, zoom: maps.map.getView().getZoom() });

    setTimeout(() => {
        feat.setStyle(null);
    }, 1500);
}